---
title: bud.config
sidebar_label: bud.config
description: Used to configure bud.js
---

import ConfigExample from '@site/src/components/example'
import MultiLanguage from '@site/src/components/multi-language'

bud.js config files are the most straight forward way of interfacing with bud.js.

- The file name should include `bud` in the name.
- The module should be located in the project root or the `./config` directory.
- The module can be written in JavaScript, TypeScript, YML or JSON5.
- JavaScript and TypeScript configurations can either export a configuration function or import bud and use it directly.

:::info esbuild-wasm

By default bud.js uses [esbuild-wasm](https://www.npmjs.com/package/esbuild-wasm) to transpile the config file when authored with TypeScript.

If you prefer you can install [esbuild](https://www.npmjs.com/package/esbuild) and it will be preferred.

The esbuild team advises that using esbuild is faster than esbuild-wasm, but the benefit of esbuild-wasm is that it doesn't need to be built during installation.

:::

## Example configurations

<ConfigExample>

```ts title=bud.config.ts
bud.entry(`app`, [`app.js`, `app.css`])
```

```js title=bud.config.js
bud.entry(`app`, [`app.js`, `app.css`])
```

```yml title=bud.config.yml
entry:
  - app
  - ['app.js', 'app.css']
```

```json title=bud.config.json
{
  "entry": ["app", ["app.js", "app.css"]]
}
```

</ConfigExample>

## Importing bud.js directly

You can import bud.js directly and use it in your configuration.

<MultiLanguage>

```ts title=bud.config.ts
import {bud} from '@roots/bud'

bud.entry(`app`, [`app.js`, `app.css`])
```

```js title=bud.config.js
import {bud} from '@roots/bud'

bud.entry(`app`, [`app.js`, `app.css`])
```

</MultiLanguage>

## Using multiple configuration files

It is possible to create more than one bud.js configuration file.

When more than one configuration file is present they are execuetd in the following order:

1. `bud.*` - the standard, base configuration.
2. `bud.local.*` - local configuration.
3. `bud.{production,development}.*` - mode specific configuration. Applied when `bud.mode` matches.
4. `bud.{production,development}.local.*` - mode specific local configuration. Applied when `bud.mode` matches.

You may want to add `bud.local.*` to your `.gitignore` file. This way contributors to your project can make specific overrides using `bud.local.*` files
without affecting the base configuration kept in source control.

## Configuring bud.js with JSON and YML

Each key is a reference to a bud.js call. The supplied values are the arguments to that call, expressed as an array.

### Calling functions

For example, the following bud.js configuration:

<MultiLanguage>

```yml title=bud.config.yml
entry:
  - app
  - app.js
```

```json title=bud.config.json
{
  "entry": ["app", "app.js"]
}
```

</MultiLanguage>

is equivalent to:

```ts title=bud.config.ts
bud.entry('app', 'app.js')
```

There is some flexibility here if you are passing a single value and it is NOT an array. So, this is okay:

```yml title=bud.config.yml
entry:
  app: app.js
```

Since it can easily be interpreted by bud.js as:

```yml title=bud.config.yml
entry:
  - app: app.js
```

Which is equivalent to a single item in array of arguments, containing an object.

```ts title=bud.config.ts
bud.entry({app: 'app.js'})
```

Conversely, since [bud.assets](/reference/bud.assets) expects an array, the following yml would cause an error:

```yml title=bud.config.yml
# This is incorrect
assets: ['src/**/*.html', 'app/**/*.html']
```

How is bud.js to know whether you intended to pass multiple parameters or a single array? It can't, and so this is the result:

```js title=bud.config.js
bud.assets('src/**/*.html', 'app/**/*.html') // wrong
// what we wanted: bud.assets(['src/**/*.html', 'app/**/*.html'])
```

To fix it, we must remember that we are passing _an array of the function parameters_, and wrap our argument in an array:

```yml title=bud.config.yml
assets:
  - ['src/**/*.html', 'app/**/*.html']
```

### Accessing nested values

You can access nested properties with standard yml indentation:

```yml title=bud.config.yml
babel:
  setPluginOptions:
    - '@babel/plugin-transform-runtime'
    - {helpers: true}
```

You can also use dot notation:

```yml title=bud.config.yml
babel.setPluginOptions:
  - '@babel/plugin-transform-runtime'
  - {helpers: true}
```

### Accessing bud values

You can make reference to the `bud` object with `_bud`.

```yml title=bud.config.yml
splitChunks: _bud.isProduction
```

You can tap `bud` with an arrow fn if needed. These functions will be called
as they are encountered and supplied with the bud.js instance.

```yml title=bud.config.yml
minimize: bud => bud.isProduction
```

This is the equivalent of:

```ts title=bud.config.ts
bud.tap('minimize', bud.isProduction)
```

### Treating a value as a function

If you need to execute some code but don't need the bud object, you can prefix a string with `=>` to indicate that it should be treated as a function. These functions will be called
as they are encountered.

This will log `4`:

```yml title=bud.config.yml
log: => 2 + 2
```

### Handling callbacks

Some functions accept functions as a value. In cases like these wrap the function in an additional `=>` so that the
config parser does not call the function itself.

```yml title=bud.config.yml
webpackConfig: >
  => config => ({...config, parallelism: 1})
```

[bud.tap](/reference/bud.tap) and [bud.tapAsync](/reference/bud.tapAsync) can be helpful for dynamic configuration and work like this:

```yml title=bud.config.yml
tap: >
  => bud => {
    // this is a very flexible
    // area to do all sorts of dynamic config stuff
    bud.log('hi!')
  }

tapAsync: >
  => async bud => {
    // same as above but async
    bud.log('hi!', '...eventually')
  }
```

If you're doing a lot of this remember that you can create JS configurations in addition to the yml one.

## Configuring bud.js with JSON

You can use [JSON5 syntax](https://json5.org), similar to what is supported in `tsconfig.json`.

```json title=bud.config.json
{
  /** Comments are fine */
  entry: ["app", ["app.js"]],
  runtime: true,
  copyDir: "assets",
  babel: {
    setPluginOptions: [
      "@babel/plugin-transform-runtime",
      {helpers: false, regenerator: false}
    ]
  }
}
```

If you are doing a lot of dynamic configuration you may find it easier to use YML or JS. Ultimately, it's your choice, but
we recommend using yml over json for more complicated configs.
